#include <configure.h>
#include <iostream>
#include <logger/logger.h>
#include <httphelper.h>
#include <loradevice.h>
#include <oiltanks.h>
#include <resources.h>
#include <lora_protocol_v1.h>
#include <model.h>
#include <sstream>
#include <iomanip>
#include <regex>
#include <loraservice.h>
#include <service.h>

ushort crc16(const uint8_t *data, size_t size)
{
    const ushort polynomial = 0xa001; // 使用的多项式
    ushort crc = 0x0000;              // 初始CRC值
    ushort flag;

    for (size_t current_byte = 0; current_byte < size; ++current_byte)
    {
        crc ^= (data[current_byte] << 8); // 将当前字节左移8位，然后与CRC值进行异或

        for (uint8_t i = 0; i < 8; ++i)
        {
            // TODO：循环8次进行每位的处理
            // 获取CRC的最高位
            flag = crc & 0x8000;
            // CRC左移1位
            crc <<= 1;
            if (flag)
            {
                // 如果最高位为1，则与多项式进行异或
                crc ^= polynomial;
            }
        }
    }

    return crc; // 返回计算得到的CRC值
}

int main()
{
    using namespace cores::common::configures;
    using namespace cores::loggers;
    using namespace cores::common;
    using namespace cores::services::v1;
    using namespace cores::services;
    using namespace cores::devices;

    LoraDeviceManager globalLoraDeviceManager;
    OilTanksManager globalOilTanksManager;
    ServiceManager globalServiceManager;

    Logger::instance()->setLogDir("./logs");

    Configure::LoadConfigInfo();
    std::cout << "station_code : " << Configure::toString("station_code") << std::endl;
    std::cout << "dept_code : " << Configure::toString("dept_code") << std::endl;
    std::cout << "config_api_url : " << Configure::toString("config_api_url") << std::endl;
    std::cout << "lora_data_topic : " << Configure::toString("lora_data_topic") << std::endl;
    std::cout << "warming_token : " << Configure::toString("warming_token") << std::endl;
    std::cout << "crc_check : " << Configure::toString("crc_check") << std::endl;
    std::cout << "auto_uograde : " << Configure::toString("auto_upgrade") << std::endl;

    LoraDeviceManager::Print();

    // uint8_t buffer[] = {0xfe, 0x30, 0x00, 0x81, 0xfa, 0x09, 0xe6, 0x00, 0x01, 0xc2, 0x7a, 0x49, 0x67, 0x82, 0x7b, 0x49, 0x67, 0x5c, 0x31, 0x2d, 0x00, 0x00, 0x01, 0x00, 0x00, 0x6c, 0xfb, 0xfe, 0xea, 0xdc, 0xde, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x95, 0xfd};

    // using namespace cores::protocols::lora_v1;
    // TransDataUpload dataUpload(buffer, 52);
    // auto transData = dataUpload.transData();
    // std::cout << transData.data_sn << std::endl
    //           << transData.lora_id << std::endl
    //           << int(transData.nozzle_code) << std::endl
    //           << int(transData.category) << std::endl
    //           << transData.amount << std::endl
    //           << transData.volume << std::endl
    //           << transData.price << std::endl
    //           << transData.encoder_val << std::endl
    //           << transData.screen_raw_data << std::endl;

    // LoraUploadProtocolParser parser;
    // if (parser.isChecked(buffer, 52))
    //     std::cout << "success" << std::endl;
    // else
    //     std::cout << "failed" << std::endl;

    // // std::stringstream tss;
    // // ss << std::hex << 100 << " " << 67 <<  " " << 145;
    // // std::cout << ss.str() << std::endl;

    // std::string s = "192.168.3.17";
    // std::string t1(".");
    // std::string t2 = " ";
    // auto pos = s.find(t1);
    // while (pos != std::string::npos)
    // {
    //     s.replace(pos, t1.length(), t2);
    //     pos += t2.length();
    //     pos = s.find(t1, pos);
    // }

    // std::cout << std::dec;
    // std::cout << __FILE__ << ":" << __LINE__ << ":" << s << std::endl;

    // std::stringstream ss(s);
    // // ss >> std::hex;
    // int t;
    // // std::cout << std::hex;
    // while (!ss.eof())
    // {
    //     ss >> t;
    //     std::cout << std::setw(3) << std::setfill('0') << t << std::endl;
    // }

    // using namespace cores::services::v1;
    // SerialNumberManager snm;
    // snm.print();

    // snm.updateTaxSerialNumber(230, 1, 100);
    // snm.updateTransSerialNumber(230, 2, 1000);

    // LoraTokenManager mg;

    // uint8_t buffer1[128];

    // for (auto i = 0; i < 10; i++)
    //     mg.toBuffer(buffer1, 128);

    LoraService service("loraservice");

    XLOG("1");
    ServiceManager::InitServices();

    auto loraIds = LoraDeviceManager::GetLoraIDVector();

    if (loraIds.empty() == false)
    {
        LoraStatusManager::UpdateConfig(loraIds.front(), true);
        LoraStatusManager::MustDownLoadConfig(loraIds.front(), true);
    }
    XLOG("2");
    ServiceManager::StartAllServices();
    XLOG("3");

    auto last = chrono::steady_clock::now();
    while (true)
    {
        auto now = chrono::steady_clock::now();
        if (chrono::duration_cast<chrono::seconds>(now - last).count() > 120)
            break;
    }

    XLOG("4");
    ServiceManager::StopAllServices();

    Logger::instance()->stop();
    XLOG("app end!");

    return 0;
}
